"""违规记录相关API路由"""

from flask import Blueprint, request, jsonify, send_file
from .auth import token_required
import logging
import os
import time
from datetime import datetime, timedelta

from database import db_service
from behavior_analysis import analysis_manager

# 创建蓝图
violations_bp = Blueprint('violations', __name__, url_prefix='/api/violations')

# 配置日志
logger = logging.getLogger('api.violations')

@violations_bp.route('/', methods=['GET'])
@token_required
def get_violations():
    """获取违规记录列表
    
    查询参数:
    - skip: 跳过记录数
    - limit: 返回记录数
    - type: 违规类型过滤
    - severity: 严重程度过滤
    - status: 状态过滤 (new/processing/resolved)
    - camera_id: 摄像头ID过滤
    - start_date: 开始日期 (YYYY-MM-DD)
    - end_date: 结束日期 (YYYY-MM-DD)
    - sort_by: 排序字段
    - sort_order: 排序方向 (asc/desc)
    
    返回:
    - 违规记录列表
    """
    try:
        # 获取查询参数
        skip = int(request.args.get('skip', 0))
        limit = int(request.args.get('limit', 50))
        violation_type = request.args.get('type')
        severity = request.args.get('severity')
        status = request.args.get('status')
        camera_id = request.args.get('camera_id', type=int)
        start_date = request.args.get('start_date')
        end_date = request.args.get('end_date')
        sort_by = request.args.get('sort_by', 'created_at')
        sort_order = request.args.get('sort_order', 'desc')
        
        # 构建过滤条件
        filters = {}
        if violation_type:
            filters['violation_type'] = violation_type
        if severity:
            filters['severity'] = severity
        if status:
            filters['status'] = status
        if camera_id is not None:
            filters['camera_id'] = camera_id
        
        # 处理日期过滤
        date_filters = {}
        if start_date:
            start_datetime = datetime.strptime(start_date, '%Y-%m-%d')
            date_filters['start'] = start_datetime
        if end_date:
            end_datetime = datetime.strptime(end_date, '%Y-%m-%d') + timedelta(days=1)
            date_filters['end'] = end_datetime
        
        # 获取违规记录
        violations = db_service.get_violations(
            skip=skip,
            limit=limit,
            sort_by=sort_by,
            sort_order=sort_order,
            date_filters=date_filters,
            **filters
        )
        
        # 获取总记录数
        total = db_service.count_violations(date_filters=date_filters, **filters)
        
        # 转换为字典格式
        result = []
        for v in violations:
            violation_dict = {
                'id': v.id,
                'type': v.violation_type,
                'severity': v.severity,
                'description': v.description,
                'image_path': v.image_path,
                'video_path': v.video_path if hasattr(v, 'video_path') else None,
                'status': v.status,
                'camera_id': v.camera_id,
                'camera_name': v.camera.name if hasattr(v, 'camera') and v.camera else None,
                'location': v.location if hasattr(v, 'location') else None,
                'confidence': v.confidence if hasattr(v, 'confidence') else None,
                'created_at': v.created_at.isoformat() if v.created_at else None,
                'updated_at': v.updated_at.isoformat() if v.updated_at else None,
                'processed_by': v.processed_by if hasattr(v, 'processed_by') else None,
                'metadata': v.metadata if hasattr(v, 'metadata') else {}
            }
            result.append(violation_dict)
        
        return jsonify({
            'violations': result,
            'total': total,
            'skip': skip,
            'limit': limit
        })
    except ValueError as e:
        return jsonify({'error': f'参数格式错误: {str(e)}'}), 400
    except Exception as e:
        logger.error(f"获取违规记录失败: {str(e)}")
        return jsonify({'error': f'服务器内部错误: {str(e)}'}), 500

@violations_bp.route('/<int:violation_id>', methods=['GET'])
@token_required
def get_violation(violation_id):
    """获取单个违规记录详情
    
    参数:
    - violation_id: 违规记录ID
    
    返回:
    - 违规记录详细信息
    """
    try:
        violation = db_service.get_violation_by_id(violation_id)
        if not violation:
            return jsonify({'error': '违规记录不存在'}), 404
        
        # 获取相关信息
        related_violations = db_service.get_related_violations(
            violation_id, 
            time_window=timedelta(minutes=30),
            limit=10
        )
        
        result = {
            'id': violation.id,
            'type': violation.violation_type,
            'severity': violation.severity,
            'description': violation.description,
            'image_path': violation.image_path,
            'video_path': violation.video_path if hasattr(violation, 'video_path') else None,
            'status': violation.status,
            'camera_id': violation.camera_id,
            'camera_name': violation.camera.name if hasattr(violation, 'camera') and violation.camera else None,
            'location': violation.location if hasattr(violation, 'location') else None,
            'confidence': violation.confidence if hasattr(violation, 'confidence') else None,
            'created_at': violation.created_at.isoformat() if violation.created_at else None,
            'updated_at': violation.updated_at.isoformat() if violation.updated_at else None,
            'processed_by': violation.processed_by if hasattr(violation, 'processed_by') else None,
            'metadata': violation.metadata if hasattr(violation, 'metadata') else {},
            'related_violations': [{
                'id': v.id,
                'type': v.violation_type,
                'created_at': v.created_at.isoformat()
            } for v in related_violations]
        }
        
        return jsonify(result)
    except Exception as e:
        logger.error(f"获取违规记录详情失败: {str(e)}")
        return jsonify({'error': f'服务器内部错误: {str(e)}'}), 500

@violations_bp.route('/<int:violation_id>/update', methods=['PUT'])
@token_required
def update_violation(violation_id):
    """更新违规记录状态
    
    参数:
    - violation_id: 违规记录ID
    
    Body参数:
    - status: 新状态 (processing/resolved)
    - processed_by: 处理人
    - notes: 处理备注
    
    返回:
    - 更新后的违规记录信息
    """
    try:
        data = request.json
        if not data:
            return jsonify({'error': '请求体不能为空'}), 400
        
        # 验证状态值
        valid_statuses = ['processing', 'resolved']
        status = data.get('status')
        if status and status not in valid_statuses:
            return jsonify({'error': f'status 必须是以下之一: {valid_statuses}'}), 400
        
        # 更新违规记录
        violation = db_service.update_violation(
            violation_id,
            status=status,
            processed_by=data.get('processed_by'),
            notes=data.get('notes')
        )
        
        if not violation:
            return jsonify({'error': '违规记录不存在'}), 404
        
        logger.info(f"更新违规记录状态: ID {violation_id}, 状态: {status}")
        
        return jsonify({
            'id': violation.id,
            'status': violation.status,
            'updated_at': violation.updated_at.isoformat() if violation.updated_at else None
        })
    except Exception as e:
        logger.error(f"更新违规记录失败: {str(e)}")
        return jsonify({'error': f'服务器内部错误: {str(e)}'}), 500

@violations_bp.route('/<int:violation_id>/image', methods=['GET'])
@token_required
def get_violation_image(violation_id):
    """获取违规记录关联的图片
    
    参数:
    - violation_id: 违规记录ID
    
    返回:
    - 图像文件
    """
    try:
        violation = db_service.get_violation_by_id(violation_id)
        if not violation:
            return jsonify({'error': '违规记录不存在'}), 404
        
        if not violation.image_path or not os.path.exists(violation.image_path):
            return jsonify({'error': '图片文件不存在'}), 404
        
        return send_file(violation.image_path, mimetype='image/jpeg')
    except Exception as e:
        logger.error(f"获取违规记录图片失败: {str(e)}")
        return jsonify({'error': f'服务器内部错误: {str(e)}'}), 500

@violations_bp.route('/statistics', methods=['GET'])
@token_required
def get_violations_statistics():
    """获取违规统计信息
    
    查询参数:
    - days: 统计天数，默认7天
    - group_by: 分组方式 (day/hour/type/camera)
    - camera_id: 摄像头ID过滤
    - type: 违规类型过滤
    
    返回:
    - 统计数据
    """
    try:
        # 获取查询参数
        days = int(request.args.get('days', 7))
        group_by = request.args.get('group_by', 'day')
        camera_id = request.args.get('camera_id', type=int)
        violation_type = request.args.get('type')
        
        # 验证分组方式
        valid_group_by = ['day', 'hour', 'type', 'camera', 'severity']
        if group_by not in valid_group_by:
            return jsonify({'error': f'group_by 必须是以下之一: {valid_group_by}'}), 400
        
        # 构建过滤条件
        filters = {}
        if camera_id is not None:
            filters['camera_id'] = camera_id
        if violation_type:
            filters['violation_type'] = violation_type
        
        # 获取统计数据
        statistics = db_service.get_violations_statistics(
            days=days,
            group_by=group_by,
            **filters
        )
        
        return jsonify({
            'statistics': statistics,
            'days': days,
            'group_by': group_by,
            'filters': filters
        })
    except ValueError as e:
        return jsonify({'error': f'参数格式错误: {str(e)}'}), 400
    except Exception as e:
        logger.error(f"获取违规统计信息失败: {str(e)}")
        return jsonify({'error': f'服务器内部错误: {str(e)}'}), 500

@violations_bp.route('/batch/update', methods=['PUT'])
@token_required
def batch_update_violations():
    """批量更新违规记录
    
    Body参数:
    - violation_ids: [1, 2, 3] 违规记录ID列表
    - status: 新状态
    - processed_by: 处理人
    
    返回:
    - 批量操作结果
    """
    try:
        data = request.json or {}
        violation_ids = data.get('violation_ids', [])
        status = data.get('status')
        processed_by = data.get('processed_by')
        
        if not isinstance(violation_ids, list):
            return jsonify({'error': 'violation_ids 必须是数组'}), 400
        
        if not violation_ids:
            return jsonify({'error': 'violation_ids 不能为空'}), 400
        
        # 验证状态值
        if status:
            valid_statuses = ['processing', 'resolved']
            if status not in valid_statuses:
                return jsonify({'error': f'status 必须是以下之一: {valid_statuses}'}), 400
        
        results = {
            'success': [],
            'failed': []
        }
        
        for violation_id in violation_ids:
            try:
                violation = db_service.update_violation(
                    violation_id,
                    status=status,
                    processed_by=processed_by
                )
                if violation:
                    results['success'].append(violation_id)
                else:
                    results['failed'].append({violation_id: '记录不存在'})
            except Exception as e:
                results['failed'].append({violation_id: str(e)})
        
        logger.info(f"批量更新违规记录: 成功 {len(results['success'])} 条, 失败 {len(results['failed'])} 条")
        
        return jsonify({
            'status': 'completed',
            'results': results,
            'total_processed': len(violation_ids),
            'total_success': len(results['success']),
            'total_failed': len(results['failed'])
        })
    except Exception as e:
        logger.error(f"批量更新违规记录失败: {str(e)}")
        return jsonify({'error': f'服务器内部错误: {str(e)}'}), 500

@violations_bp.route('/export', methods=['GET'])
@token_required
def export_violations():
    """导出违规记录
    
    查询参数:
    - format: 导出格式 (csv/excel)
    - start_date: 开始日期
    - end_date: 结束日期
    - type: 违规类型过滤
    - status: 状态过滤
    
    返回:
    - 导出文件
    """
    try:
        # 获取查询参数
        export_format = request.args.get('format', 'csv')
        start_date = request.args.get('start_date')
        end_date = request.args.get('end_date')
        violation_type = request.args.get('type')
        status = request.args.get('status')
        
        # 验证格式
        if export_format not in ['csv', 'excel']:
            return jsonify({'error': '格式必须是 csv 或 excel'}), 400
        
        # 构建过滤条件
        filters = {}
        if violation_type:
            filters['violation_type'] = violation_type
        if status:
            filters['status'] = status
        
        # 处理日期过滤
        date_filters = {}
        if start_date:
            date_filters['start'] = datetime.strptime(start_date, '%Y-%m-%d')
        if end_date:
            date_filters['end'] = datetime.strptime(end_date, '%Y-%m-%d') + timedelta(days=1)
        
        # 导出违规记录
        file_path = db_service.export_violations(
            format=export_format,
            date_filters=date_filters,
            **filters
        )
        
        # 生成文件名
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        filename = f'violations_{timestamp}.{export_format}'
        
        return send_file(
            file_path,
            as_attachment=True,
            download_name=filename,
            mimetype='text/csv' if export_format == 'csv' else 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
    except ValueError as e:
        return jsonify({'error': f'参数格式错误: {str(e)}'}), 400
    except Exception as e:
        logger.error(f"导出违规记录失败: {str(e)}")
        return jsonify({'error': f'服务器内部错误: {str(e)}'}), 500

@violations_bp.route('/types', methods=['GET'])
@token_required
def get_violation_types():
    """获取所有违规类型
    
    返回:
    - 违规类型列表
    """
    try:
        # 从数据库获取所有违规类型
        violation_types = db_service.get_violation_types()
        
        return jsonify({
            'types': violation_types,
            'total': len(violation_types)
        })
    except Exception as e:
        logger.error(f"获取违规类型失败: {str(e)}")
        return jsonify({'error': f'服务器内部错误: {str(e)}'}), 500


@violations_bp.route('/<int:violation_id>/confirm', methods=['POST'])
@token_required
def confirm_violation(violation_id):
    """确认违规记录
    
    参数:
    - violation_id: 违规记录ID
    
    Body参数:
    - confirmed: 是否确认 (true/false)
    - notes: 确认备注
    
    返回:
    - 确认结果
    """
    try:
        data = request.json
        if not data:
            return jsonify({'error': '请求体不能为空'}), 400
        
        confirmed = data.get('confirmed', False)
        notes = data.get('notes', '')
        
        # 从请求上下文获取用户ID
        current_user = request.user_id
        
        # 确认违规记录
        violation = db_service.confirm_violation(
            violation_id,
            confirmed=confirmed,
            confirmed_by=current_user,
            notes=notes
        )
        
        if not violation:
            return jsonify({'error': '违规记录不存在'}), 404
        
        logger.info(f"确认违规记录: ID {violation_id}, 确认状态: {confirmed}")
        
        return jsonify({
            'id': violation.id,
            'confirmed': confirmed,
            'confirmed_by': current_user,
            'updated_at': violation.updated_at.isoformat() if violation.updated_at else None
        })
    except Exception as e:
        logger.error(f"确认违规记录失败: {str(e)}")
        return jsonify({'error': f'服务器内部错误: {str(e)}'}), 500